Fix KTO evaluate crash on streaming datasets with unpaired-preference data#6325
Conversation
|
The docs for this PR live here. All of your documentation changes will be reflected on that endpoint. The docs are available until 30 days after the last update. |
Why this isn't gated on an Accelerate versionWhile debugging the Turns out that's misleading: Accelerate 1.13.0 added a short-circuit in concatenate() that returns a single gathered batch as-is instead of type-checking it.
Confirmed with the Accelerate maintainers themselves in the PR review thread (huggingface/accelerate#3850 (comment)): they explicitly acknowledged multi-process support was out of scope for that fix
I opened a GH issue to track this as a documented, discoverable limitation: So: real distributed streaming evaluation with KTO's unpaired-preference collator would still crash today, on any Accelerate version, without this fix. The fix here ("label" as a tensor, matching every other collated field) is the correct, version-independent solution, not something to conditionally apply only for old Accelerate. |
qgallouedec
left a comment
There was a problem hiding this comment.
nice. Plus, it's more consistent to have collators that only return tensors
This PR fixes streaming evaluation for KTOTrainer with unpaired-preference data, where a batch field returned as a plain list broke Accelerate's dispatch mechanism for IterableDataset.
See: https://github.com/huggingface/trl/actions/runs/28934157283/job/85840257000?pr=6326
Traceback:
Motivation
DataCollatorForUnpairedPreferenceandDataCollatorForVisionUnpairedPreferencereturned the "label" batch field as a plain Python list of booleans instead of a tensor, while every other field in the batch was a tensor. This works fine with a map-styleDataset, but Accelerate'sDataLoaderDispatcher, used for streaming IterableDatasets, needs every batch field to be a tensor so it can concatenate and redistribute sub-batches across processes. Passing a streaming eval dataset toKTOTrainer.evaluate()therefore raisedTypeError: Can only concatenate tensors but got <class 'bool'>.Note this is not an Accelerate-version-specific issue. Accelerate ≥1.13.0 added a short-circuit in
concatenate()that happens to skip the crash whennum_processes == 1(see huggingface/accelerate#4111, which the Accelerate maintainers confirm is a partial, single-process-only fix). Real multi-process/distributed streaming evaluation still crashes on every Accelerate version, old and new. So this fix is required unconditionally, regardless of installed Accelerate version.Solution
"label" is now built with
torch.tensor(...)in both collators, consistent with every other returned field. Docstrings and doctest examples were updated to reflect the new tensor output.Changes
DataCollatorForUnpairedPreference.torch_callandDataCollatorForVisionUnpairedPreference.torch_calltest_padding_and_masksassertion for the new tensor typeKTOTrainer.evaluate()with anIterableDatasetNote
Low Risk
Narrow collator output change; loss code already accepts labels via
torch.tensor/torch.as_tensor, with regression coverage for streaming eval.Overview
Fixes
KTOTrainer.evaluate()crashing on streamingIterableDataseteval when Accelerate’s dataloader dispatcher tries to concatenate batch fields and hits a plain Python list of booleans forlabel.DataCollatorForUnpairedPreferenceandDataCollatorForVisionUnpairedPreferencenow buildlabelwithtorch.tensor(...), matching other batch fields and satisfying Accelerate’s tensor-only concatenation (see accelerate#4111). Docstrings and doctest examples were updated accordingly.Tests assert tensor labels in
test_padding_and_masksand addtest_evaluate_with_iterable_datasetfor end-to-end streaming evaluation withapo_zero_unpaired(no KL term on streaming data).Reviewed by Cursor Bugbot for commit b268a72. Bugbot is set up for automated code reviews on this repo. Configure here.